#ifndef PBVP_DCT_CONSTRUCTOR_H
#define PBVP_DCT_CONSTRUCTOR_H

#include "../data/reg3dvolumedata.h"
#include "../contree/augmentedctree.h"
#include "../contree/volume3dcritical.h"
#include "../sdf/dynarray.h"
#include "dct_node.h"

namespace PBVP {
	class DualGraph;
	class CutVertex;
    /**
	 * This class construct dual contour tree (DCT) from CT and 
	 * compute the attributes of DCT nodes
     */
	class DCTConstructor {
	public:
		/**
         * Constructor
         */
		DCTConstructor(Reg3DVolumeData *pData, AugmentedContourTree *pCTree);

		/**
         * Destructor
         */
		~DCTConstructor();

		/// Compute Attributes of a DCT node
		/**
		 * @param pDCTNode 
		 */
		void computeNodeAttributes(DualNode *pDCTNode);

		/** 
		 * @param pDCTNode 
		 * @param upperSurface
		 * 
		 * @return GeometryData*
		 */
		GeometryData* extractDCTNodeSurface(DualNode *pDCTNode, bool upperSurface = true);

		/** 
		 * Construct a Dual Contour Tree(Graph) from Contour Tree 
		 *  
		 * @param fmin
		 * @param fmax
		 * @param numLevels
		 * 
		 * @return DualGraph*
		 */
		DualGraph* buildDualGraph(float fmin, float fmax, int numLevels);

	private:
		///
		Reg3DVolumeData* m_pData;
		///
		Volume3DCritical* m_pVolCritical;
		///
		AugmentedContourTree *m_pACTree;

		CutVertex* cutContourTree(float x, int& nv);

		/// Build a functional range of dual nodes
		/**
		* @param ir: The range index
		*/
		void buildRange(DualGraph *pDCTree, int ir, dynamic_array<int>& crit_pnts, CutVertex* low_verts, int nl,
			CutVertex* up_verts, int nu, std::map<int, CutVertex*> *cut_maps, int levels[]);

		/// Compute the attributes of a DCT node
		/**
		* 
		* @param node
		* @param arc
		*/
		void computeDCTNodeAttrib (DualNode* node, SuperArc& arc, float cut_val);
	};
}

#endif